/**
 * 
 */
package org.istt.dao.hibernate;

import java.sql.SQLException;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.istt.dao.WorkflowProcessDao;
import org.istt.domain.WorkflowProcess;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.stereotype.Repository;

/**
 * @author NDTHO
 *
 */
@Repository("workflowProcessDao")
public class WorkflowProcessDaoHibernate extends BaseDaoHibernate<WorkflowProcess, Long> implements
		WorkflowProcessDao {
	@Autowired
	public WorkflowProcessDaoHibernate(SessionFactory sessionFactory) {
		super(sessionFactory);
	}

	/*@Override
	public void removeByWorkflow(final Workflow workflow) {
		
		String hsql = "delete WorkflowProcess wp where workflow.id = " + workflow.getId();
		hibernateTemplate.bulkUpdate(hsql);
		
		@SuppressWarnings("unchecked")
		List<WorkflowProcess> lstmenu =  (List<WorkflowProcess>)hibernateTemplate.execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException,	SQLException {
						Criteria criteria = session.createCriteria(WorkflowProcess.class);
						criteria.add(Restrictions.eq("workflow", workflow));
						return criteria.list();
			}
		});
		if(lstmenu!=null && lstmenu.size()!=0)  removeEntities(lstmenu);
	}*/
	
	/*public WorkflowProcess getById(final Long wfid){
		WorkflowProcess wfpr =  (WorkflowProcess)hibernateTemplate.execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException,	SQLException {
						Criteria criteria = session.createCriteria(WorkflowProcess.class);
						criteria.add(Restrictions.eq("id", wfid));
						return criteria.uniqueResult();
			}
		});
		
		return wfpr;
	}*/
	
	/*
	 * (non-Javadoc)
	 * @see org.istt.dao.WorkflowProcessDao#getFirstStepOfWorkflow(java.lang.Long)
	 */
	@Override
	public WorkflowProcess getFirstStepOfWorkflow(final Long wfpId) {
		return hibernateTemplate.execute(new HibernateCallback<WorkflowProcess>() {
			@Override
			public WorkflowProcess doInHibernate(Session session) throws HibernateException,	SQLException {
						Criteria criteria = session.createCriteria(WorkflowProcess.class);
						criteria.add(Restrictions.eq("position", WorkflowProcess.START_POSITION)).createCriteria("workflow").add(Restrictions.idEq(wfpId));
						return (WorkflowProcess)criteria.uniqueResult();
			}
		});
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.istt.dao.WorkflowProcessDao#getFinalStepOfWorkflow(java.lang.Long)
	 */
	@Override
	public WorkflowProcess getFinalStepOfWorkflow(final Long wfpId) {
		return hibernateTemplate.execute(new HibernateCallback<WorkflowProcess>() {
			@Override
			public WorkflowProcess doInHibernate(Session session) throws HibernateException,	SQLException {
				StringBuilder builder = new StringBuilder();
				builder.append("select {w.*} ");
				builder.append("from TBL_WORKFLOW_PROCESS w ");
				builder.append("where POSITION = (select top 1 MAX(POSITION) over(PARTITION BY workflow_id) from TBL_WORKFLOW_PROCESS where WORKFLOW_ID =:wfid) ");
				builder.append("and WORKFLOW_ID =:wfid ");
				
				return (WorkflowProcess)session.createSQLQuery(builder.toString())
										.addEntity("w", WorkflowProcess.class)
										.setParameter("wfid", wfpId)
										.uniqueResult();
				
			}
		});
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.istt.dao.WorkflowProcessDao#getNextStepOfWorkflow(java.lang.String, java.lang.Integer, java.lang.Long)
	 */
	@Override
	public WorkflowProcess getNextStepOfWorkflow(final String fileId, final Integer nextPos, final Long processStatusId) {
		
		return hibernateTemplate.execute(new HibernateCallback<WorkflowProcess>() {
			@Override
			public WorkflowProcess doInHibernate(Session session) throws HibernateException,	SQLException {
						Criteria criteria = session.createCriteria(WorkflowProcess.class);
						//criteria.add(Restrictions.eq("position", WorkflowProcess.START_POSITION)).createCriteria("workflow").add(Restrictions.idEq(position));
						if (nextPos != 0) {
						criteria.add(Restrictions.eq("position", nextPos));
						}
						criteria.setFetchMode("ProcessStatus", FetchMode.JOIN)
						.setFetchMode("Workflow", FetchMode.JOIN)
						.setFetchMode("Category", FetchMode.JOIN)
						.setFetchMode("File", FetchMode.JOIN)
						;
						criteria.createAlias("processStatus", "t1");
						criteria.createAlias("workflow", "t2");
						criteria.createAlias("t2.categories", "t3");
						criteria.createAlias("t3.files", "t4");

						if (fileId != null) {
							criteria.add(Restrictions.eq("t4.id", fileId));
						}
						if (processStatusId != null) {
							criteria.add(Restrictions.eq("t1.id", processStatusId));
						}						
						return (WorkflowProcess)criteria.uniqueResult();
			}
		});
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<WorkflowProcess> getWorkflowProcesses(Long workflowId) {
		return hibernateTemplate.find("from WorkflowProcess wp where wp.workflow.id = ? order by wp.position", new Object[]{workflowId});
	}

	/*@Override
	public void updateWfPermission(WorkflowProcess wf) {
		
		makePersistent(wf);
	}	*/
}
